package com.xwj.exception.unified.asserts;

import com.xwj.exception.unified.exception.base.BaseException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.Collection;
import java.util.Map;

/**
 * 异常断言，提供简便的条件判断，当不满足断言时，抛出异常
 *
 * 在断言接口中，所有断言方法都是使用默认方法定义的，当不满足条件抛出的异常，需要由 newException 接口方法提供。
 * 这样的设计更有利于业务场景的拓展，在不同业务场景中抛出不同的异常类型和特定的异常码等信息。
 */
public interface Assert {

    /**
     * 创建异常的接口，具体异常可由实现类来决定
     *
     * @return
     */
    BaseException newException();

    /**
     * 创建异常的接口，具体异常可由实现类来决定
     *
     * @param args message 占位符对应的参数列表
     * @return
     */
    BaseException newException(Object... args);

    /**
     * @param obj 待判断对象
     */
    default void isNotNull(Object obj) {
        isNotNull(obj, null);
    }

    /**
     * @param obj  待判断对象
     * @param args message 占位符对应的参数列表
     */
    default void isNotNull(Object obj, Object... args) {
        if (obj == null) {
            throw args == null ? newException() : newException(args);
        }
    }

    /**
     * @param obj 待判断对象
     */
    default void isNull(Object obj) {
        isNull(obj, null);
    }

    /**
     * @param obj 待判断对象
     * @param args message 占位符对应的参数列表
     */
    default void isNull(Object obj, Object... args) {
        if (obj != null) {
            throw args == null ? newException() : newException(args);
        }
    }

    /**
     * @param str 字符串
     */
    default void isNotBlank(String str) {
        isNotBlank(str, null);
    }

    /**
     * @param str 字符串
     * @param args message 占位符对应的参数列表
     */
    default void isNotBlank(String str, Object... args) {
        if (StringUtils.isBlank(str)) {
            throw args == null ? newException() : newException(args);
        }
    }

    /**
     * @param str 字符串
     */
    default void isBlank(String str) {
        isBlank(str, null);
    }

    /**
     * @param str 字符串
     * @param args message 占位符对应的参数列表
     */
    default void isBlank(String str, Object... args) {
        if (StringUtils.isNotBlank(str)) {
            throw args == null ? newException() : newException(args);
        }
    }

    /**
     * @param expression 表达式
     */
    default void isTrue(boolean expression) {
        isTrue(expression, null);
    }

    /**
     * @param expression 表达式
     * @param args message 占位符对应的参数列表
     */
    default void isTrue(boolean expression, Object... args) {
        if (!expression) {
            throw args == null ? newException() : newException(args);
        }
    }

    /**
     * @param array 数组
     */
    default void notEmpty(Object[] array) {
        notEmpty(array, null);
    }

    /**
     * @param array 数组
     * @param args message 占位符对应的参数列表
     */
    default void notEmpty(Object[] array, Object... args) {
        if (ObjectUtils.isEmpty(array)) {
            throw args == null ? newException() : newException(args);
        }
    }

    /**
     * @param collection 集合
     */
    default void notEmpty(Collection<?> collection) {
        notEmpty(collection, null);
    }

    /**
     * @param collection 集合
     * @param args message 占位符对应的参数列表
     */
    default void notEmpty(Collection<?> collection, Object... args) {
        if (CollectionUtils.isEmpty(collection)) {
            throw args == null ? newException() : newException(args);
        }
    }

    /**
     * @param map 键值对
     */
    default void notEmpty(Map<?, ?> map) {
        notEmpty(map, null);
    }

    /**
     * @param map 键值对
     * @param args message 占位符对应的参数列表
     */
    default void notEmpty(Map<?, ?> map, Object... args) {
        if (CollectionUtils.isEmpty(map)) {
            throw args == null ? newException() : newException(args);
        }
    }

    /**
     * @param type 类型
     * @param obj 对象
     */
    default void isInstanceOf(Class<?> type, Object obj) {
        isInstanceOf(type, obj, null);
    }

    /**
     * @param type 类型
     * @param obj 对象
     * @param args message 占位符对应的参数列表
     */
    default void isInstanceOf(Class<?> type, Object obj, Object... args) {
        isNotNull(type, "要检查的类型不能为空");
        if (!type.isInstance(obj)) {
            throw args == null ? newException() : newException(args);
        }
    }
}
